using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using Microsoft.EntityFrameworkCore;
using RAG.Application.Interfaces;
using RAG.Application.Dtos;
using RAG.Infrastructure.Data;
using RAG.Application.Commands;

namespace RAG.Api.Controllers;

[ApiController]
[Route("api/[controller]")]
[Authorize]
public class QAController : ControllerBase
{
    private readonly IAppRagService _ragService;
    private readonly RagDbContext _db;

    public QAController(IAppRagService ragService, RagDbContext db)
    {
        _ragService = ragService;
        _db = db;
    }

    /// <summary>
    /// 调试接口：检查数据库状态
    /// </summary>
    [HttpGet("debug-db-status")]
    public async Task<IActionResult> DebugDatabaseStatus()
    {
        try
        {
            var result = await _ragService.DebugDatabaseStatusAsync();
            return Ok(result);
        }
        catch (Exception ex)
        {
            return StatusCode(500, ApiResult.Failed((int)ApiStatusCode.INTERNAL_ERROR, $"调试数据库状态时发生错误: {ex.Message}"));
        }
    }

    /// <summary>
    /// 获取问答列表
    /// </summary>
    [HttpGet]
    public async Task<IActionResult> GetQAList([FromQuery] int page = 1, [FromQuery] int pageSize = 10)
    {
        try
        {
            var userIdClaim = User.FindFirst("sub")?.Value
                ?? User.FindFirst("user_id")?.Value
                ?? User.FindFirst("uid")?.Value;

            if (string.IsNullOrEmpty(userIdClaim) || !Guid.TryParse(userIdClaim, out var userId))
            {
                return BadRequest(ApiResult.Failed((int)ApiStatusCode.BAD_REQUEST, "无法获取用户信息"));
            }

            var result = await _ragService.GetQAListAsync(userId, page, pageSize);
            return Ok(result);
        }
        catch (Exception ex)
        {
            return StatusCode(500, ApiResult.Failed((int)ApiStatusCode.INTERNAL_ERROR, $"获取问答列表时发生错误: {ex.Message}"));
        }
    }

    /// <summary>
    /// 生成答案
    /// </summary>
    [HttpPost("generate-answer")]
    public async Task<IActionResult> GenerateAnswer([FromBody] GenerateAnswerDto dto)
    {
        try
        {
            var userIdClaim = User.FindFirst("sub")?.Value
                ?? User.FindFirst("user_id")?.Value
                ?? User.FindFirst("uid")?.Value;

            if (string.IsNullOrEmpty(userIdClaim) || !Guid.TryParse(userIdClaim, out var userId))
            {
                return BadRequest(ApiResult.Failed((int)ApiStatusCode.BAD_REQUEST, "无法获取用户信息"));
            }

            dto.UserId = userId;
            var result = await _ragService.GenerateAnswerAsync(dto);
            
            if (result.Code == 200)
            {
                return Ok(result);
            }
            else
            {
                return BadRequest(result);
            }
        }
        catch (Exception ex)
        {
            return StatusCode(500, ApiResult.Failed((int)ApiStatusCode.INTERNAL_ERROR, $"生成答案时发生错误: {ex.Message}"));
        }
    }

    /// <summary>
    /// 创建会话
    /// </summary>
    [HttpPost("sessions")]
    public async Task<IActionResult> CreateSession([FromBody] CreateSessionDto dto)
    {
        try
        {
            var userIdClaim = User.FindFirst("sub")?.Value
                ?? User.FindFirst("user_id")?.Value
                ?? User.FindFirst("uid")?.Value;

            if (string.IsNullOrEmpty(userIdClaim) || !Guid.TryParse(userIdClaim, out var userId))
            {
                return BadRequest(ApiResult.Failed((int)ApiStatusCode.BAD_REQUEST, "无法获取用户信息"));
            }

            dto.UserId = userId;
            var result = await _ragService.CreateSessionAsync(dto);
            
            if (result.Code == 200)
            {
                return Ok(result);
            }
            else
            {
                return BadRequest(result);
            }
        }
        catch (Exception ex)
        {
            return StatusCode(500, ApiResult.Failed((int)ApiStatusCode.INTERNAL_ERROR, $"创建会话时发生错误: {ex.Message}"));
        }
    }

    /// <summary>
    /// 获取会话列表
    /// </summary>
    [HttpGet("sessions")]
    public async Task<IActionResult> GetSessions()
    {
        try
        {
            var userIdClaim = User.FindFirst("sub")?.Value
                ?? User.FindFirst("user_id")?.Value
                ?? User.FindFirst("uid")?.Value;

            if (string.IsNullOrEmpty(userIdClaim) || !Guid.TryParse(userIdClaim, out var userId))
            {
                return BadRequest(ApiResult.Failed((int)ApiStatusCode.BAD_REQUEST, "无法获取用户信息"));
            }

            var result = await _ragService.GetSessionsAsync(userId);
            return Ok(result);
        }
        catch (Exception ex)
        {
            return StatusCode(500, ApiResult.Failed((int)ApiStatusCode.INTERNAL_ERROR, $"获取会话列表时发生错误: {ex.Message}"));
        }
    }

    /// <summary>
    /// 获取会话详情
    /// </summary>
    [HttpGet("sessions/{sessionId}")]
    public async Task<IActionResult> GetSession(Guid sessionId)
    {
        try
        {
            var result = await _ragService.GetSessionAsync(sessionId);
            
            if (result.Code == 200)
            {
                return Ok(result);
            }
            else
            {
                return BadRequest(result);
            }
        }
        catch (Exception ex)
        {
            return StatusCode(500, ApiResult.Failed((int)ApiStatusCode.INTERNAL_ERROR, $"获取会话详情时发生错误: {ex.Message}"));
        }
    }

    /// <summary>
    /// 更新会话（修改标题/状态/元数据）
    /// </summary>
    [HttpPut("sessions/{sessionId}")]
    public async Task<IActionResult> UpdateSession(Guid sessionId, [FromBody] UpdateSessionDto dto)
    {
        try
        {
            var userIdClaim = User.FindFirst("sub")?.Value
                ?? User.FindFirst("user_id")?.Value
                ?? User.FindFirst("uid")?.Value;

            if (string.IsNullOrEmpty(userIdClaim) || !Guid.TryParse(userIdClaim, out var userId))
            {
                return BadRequest(ApiResult.Failed((int)ApiStatusCode.BAD_REQUEST, "无法获取用户信息"));
            }

            dto.SessionId = sessionId;
            dto.UserId = userId;
            var result = await _ragService.UpdateSessionAsync(dto);

            if (result.Code == 200)
            {
                return Ok(result);
            }
            else
            {
                return BadRequest(result);
            }
        }
        catch (Exception ex)
        {
            return StatusCode(500, ApiResult.Failed((int)ApiStatusCode.INTERNAL_ERROR, $"更新会话时发生错误: {ex.Message}"));
        }
    }

    /// <summary>
    /// 更新会话（简化版，使用POST，Body携带sessionId）
    /// </summary>
    [HttpPost("sessions/update")]
    public async Task<IActionResult> UpdateSessionSimple([FromBody] UpdateSessionDto dto)
    {
        try
        {
            var userIdClaim = User.FindFirst("sub")?.Value
                ?? User.FindFirst("user_id")?.Value
                ?? User.FindFirst("uid")?.Value;

            if (string.IsNullOrEmpty(userIdClaim) || !Guid.TryParse(userIdClaim, out var userId))
            {
                return BadRequest(ApiResult.Failed((int)ApiStatusCode.BAD_REQUEST, "无法获取用户信息"));
            }

            dto.UserId = userId;
            var result = await _ragService.UpdateSessionAsync(dto);

            if (result.Code == 200)
            {
                return Ok(result);
            }
            else
            {
                return BadRequest(result);
            }
        }
        catch (Exception ex)
        {
            return StatusCode(500, ApiResult.Failed((int)ApiStatusCode.INTERNAL_ERROR, $"更新会话时发生错误: {ex.Message}"));
        }
    }

    /// <summary>
    /// 删除会话
    /// </summary>
    [HttpDelete("sessions/{sessionId}")]
    public async Task<IActionResult> DeleteSession(Guid sessionId)
    {
        try
        {
            var userIdClaim = User.FindFirst("sub")?.Value
                ?? User.FindFirst("user_id")?.Value
                ?? User.FindFirst("uid")?.Value;

            if (string.IsNullOrEmpty(userIdClaim) || !Guid.TryParse(userIdClaim, out var userId))
            {
                return BadRequest(ApiResult.Failed((int)ApiStatusCode.BAD_REQUEST, "无法获取用户信息"));
            }

            var result = await _ragService.DeleteSessionAsync(sessionId, userId);
            
            if (result.Code == 200)
            {
                return Ok(result);
            }
            else
            {
                return BadRequest(result);
            }
        }
        catch (Exception ex)
        {
            return StatusCode(500, ApiResult.Failed((int)ApiStatusCode.INTERNAL_ERROR, $"删除会话时发生错误: {ex.Message}"));
        }
    }

    /// <summary>
    /// 删除对话（无需权限）
    /// </summary>
    [HttpDelete("conversations/{conversationId}")]
    [AllowAnonymous]
    public async Task<IActionResult> DeleteConversation(Guid conversationId)
    {
        try
        {
            // 查找对话记录
            var conversation = await _db.Conversations
                .FirstOrDefaultAsync(c => c.Id == conversationId);

            if (conversation == null)
            {
                return NotFound(ApiResult.Failed((int)ApiStatusCode.NOT_FOUND, "对话记录不存在"));
            }

            // 删除对话记录
            _db.Conversations.Remove(conversation);
            await _db.SaveChangesAsync();

            return Ok(ApiResult.Success("对话删除成功"));
        }
        catch (Exception ex)
        {
            return StatusCode(500, ApiResult.Failed((int)ApiStatusCode.INTERNAL_ERROR, $"删除对话时发生错误: {ex.Message}"));
        }
    }

    /// <summary>
    /// 删除会话（无需权限）
    /// </summary>
    [HttpDelete("sessions/{sessionId}/no-auth")]
    [AllowAnonymous]
    public async Task<IActionResult> DeleteSessionNoAuth(Guid sessionId)
    {
        try
        {
            // 查找会话
            var session = await _db.Sessions
                .Include(s => s.Conversations)
                .FirstOrDefaultAsync(s => s.Id == sessionId);

            if (session == null)
            {
                return NotFound(ApiResult.Failed((int)ApiStatusCode.NOT_FOUND, "会话不存在"));
            }

            // 删除会话及其相关的对话记录
            _db.Conversations.RemoveRange(session.Conversations);
            _db.Sessions.Remove(session);
            await _db.SaveChangesAsync();

            return Ok(ApiResult.Success("会话删除成功"));
        }
        catch (Exception ex)
        {
            return StatusCode(500, ApiResult.Failed((int)ApiStatusCode.INTERNAL_ERROR, $"删除会话时发生错误: {ex.Message}"));
        }
    }

    /// <summary>
    /// 发送消息
    /// </summary>
    [HttpPost("sessions/{sessionId}/messages")]
    public async Task<IActionResult> SendMessage(Guid sessionId, [FromBody] SendMessageDto dto)
    {
        try
        {
            var userIdClaim = User.FindFirst("sub")?.Value
                ?? User.FindFirst("user_id")?.Value
                ?? User.FindFirst("uid")?.Value;

            if (string.IsNullOrEmpty(userIdClaim) || !Guid.TryParse(userIdClaim, out var userId))
            {
                return BadRequest(ApiResult.Failed((int)ApiStatusCode.BAD_REQUEST, "无法获取用户信息"));
            }

            dto.SessionId = sessionId;
            dto.UserId = userId;
            var result = await _ragService.SendMessageAsync(dto);
            
            if (result.Code == 200)
            {
                return Ok(result);
            }
            else
            {
                return BadRequest(result);
            }
        }
        catch (Exception ex)
        {
            return StatusCode(500, ApiResult.Failed((int)ApiStatusCode.INTERNAL_ERROR, $"发送消息时发生错误: {ex.Message}"));
        }
    }

    /// <summary>
    /// 获取会话消息历史
    /// </summary>
    [HttpGet("sessions/{sessionId}/messages")]
    public async Task<IActionResult> GetSessionMessages(Guid sessionId)
    {
        try
        {
            var result = await _ragService.GetSessionMessagesAsync(sessionId);
            
            if (result.Code == 200)
            {
                return Ok(result);
            }
            else
            {
                return BadRequest(result);
            }
        }
        catch (Exception ex)
        {
            return StatusCode(500, ApiResult.Failed((int)ApiStatusCode.INTERNAL_ERROR, $"获取消息历史时发生错误: {ex.Message}"));
        }
    }

    /// <summary>
    /// 检索相关文档块
    /// </summary>
    [HttpGet("retrieve-chunks")]
    public async Task<IActionResult> RetrieveChunks([FromQuery] string query, [FromQuery] Guid? knowledgeBaseId = null, [FromQuery] int topK = 5)
    {
        try
        {
            if (string.IsNullOrEmpty(query))
            {
                return BadRequest(ApiResult.Failed((int)ApiStatusCode.BAD_REQUEST, "查询内容不能为空"));
            }

            var result = await _ragService.RetrieveRelevantChunksAsync(query, knowledgeBaseId, topK);
            
            if (result.Code == 200)
            {
                return Ok(result);
            }
            else
            {
                return BadRequest(result);
            }
        }
        catch (Exception ex)
        {
            return StatusCode(500, ApiResult.Failed((int)ApiStatusCode.INTERNAL_ERROR, $"检索文档块时发生错误: {ex.Message}"));
        }
    }

    /// <summary>
    /// 获取用户对话记录
    /// </summary>
    [HttpPost("user-conversations")]
    public async Task<IActionResult> GetUserConversations([FromBody] GetUserConversationsDto dto)
    {
        try
        {
            var userIdClaim = User.FindFirst("sub")?.Value
                ?? User.FindFirst("user_id")?.Value
                ?? User.FindFirst("uid")?.Value;

            if (string.IsNullOrEmpty(userIdClaim) || !Guid.TryParse(userIdClaim, out var userId))
            {
                return BadRequest(ApiResult.Failed((int)ApiStatusCode.BAD_REQUEST, "无法获取用户信息"));
            }

            dto.UserId = userId;
            var result = await _ragService.GetUserConversationsAsync(dto);
            
            if (result.Code == 200)
            {
                return Ok(result);
            }
            else
            {
                return BadRequest(result);
            }
        }
        catch (Exception ex)
        {
            return StatusCode(500, ApiResult.Failed((int)ApiStatusCode.INTERNAL_ERROR, $"获取用户对话记录时发生错误: {ex.Message}"));
        }
    }
}
